---
import { getCollection } from "astro:content";
import { SITE, RANK_LIST } from "@config";
import Footer from "@components/Footer.astro";
import Header from "@components/Header.astro";
import Layout from "./Layout.astro";

export interface Props {
  rankResult: Map<string, Array<[string, {count: number, avatar: string}]>>;
}

let paginatedPosts = await getCollection("posts", (entry: unknown) => true);

// use all the post data to init the nameRank
function getRank() {
  let nameRank = new Map(); // structure: {"<status>" => Map<name, {count: number, avatar: string}>}
  let rankResult = new Map();
  let personRank = new Map(); // structure: {"<name>" => {count: number, avatar: string}}
  let weightMap: Map<string, number> = new Map(); // structure: {"<status>" => weight}
  
    // set all nameRank as {"status": Map()}, e.g. {"translator": Map(), "proofreader": Map()}
  RANK_LIST.forEach(({status, weight}) => {
    nameRank.set(status, new Map());
    weightMap.set(status, weight);
  });
  
  // init all the tags rank
  nameRank.forEach((value, key) => {
    let oneRank = value;
    // for each post, update the count for each tag
    for (let i = 0; i < paginatedPosts.length; i++) {
      const needToRank : {[key: string]: {expect_status: string}} = {
        "collector": { "expect_status": ""},
        "translator": { "expect_status": "translating"},
        "proofreader": { "expect_status": "proofreading"},
        "publisher": { "expect_status": ""}
      };
      // key not in needToRank, skip
      if (!needToRank.hasOwnProperty(key)) {
        continue;
      }
      // get data from post
      const {data}: {data: any} = paginatedPosts[i];
      // get the name from post
      let name = data[key];
      // set the count and avatar for each tag
      let rankPerson = "";
      if (name) {
        if (data.status != needToRank[key].expect_status) {
          rankPerson = name;
        }
      }
      // remove 'HCTT' and '' from the rank list
      if (rankPerson === "" || rankPerson === "HCTT") {
        continue;
      }
      if (oneRank.has(rankPerson)) {
          // update count
          let thisRank = oneRank.get(rankPerson);
          thisRank.count += 1;
          oneRank.set(rankPerson, thisRank);
        } else {
          oneRank.set(rankPerson, { count: 1, avatar: "https://github.com/" + rankPerson + ".png"});
        }
    }
    // 计算单人的总分
    oneRank.forEach((partCount: { count: number; avatar: string; }, personName: string) => {
      let thisPersonPartCount = partCount.count * (weightMap.get(key) ?? 0);
      if (personRank.has(personName)) {
        let thisPerson = personRank.get(personName);
        thisPerson.count += thisPersonPartCount;
        personRank.set(personName, thisPerson);
      } else {
        personRank.set(personName, { count: thisPersonPartCount, avatar: partCount.avatar});
      }
    });
  });
  // 更新单人的总分
  nameRank.set("all", personRank);
  
  // sort all the tags and store the result in "rankResult"
  nameRank.forEach((value, key) => {
    let oneRank = value;
    let sortedRank = [...oneRank].sort((a, b) => b[1].count - a[1].count);
    rankResult.set(key, sortedRank);
  });

  return rankResult;
}

let rankResult = getRank();

// Get the avatar by Github API 'https://api.github.com/search/users?q='
async function getAvatar(name: string) {
  let avatar = "https://github.com/identicons/" + name + ".png"; // random default avatar https://github.com/identicons/${name}.png
  const response = await fetch(`https://api.github.com/search/users?q=${name}`);
  const data = await response.json();
  if (data.hasOwnProperty("items") && data.items.length > 0) {
    avatar = data.items[0].avatar_url;
  }
  return avatar;
}

async function getAllAvatar() {
  // update the avatar for each tag
  let newRankResult = new Map();

  // Create an array to store all the promises
  let promises: any[] = [];

  rankResult.forEach((value, key) => {
    let oneRank = value;
    oneRank.forEach(([name, feature]: [string, {count: number, avatar: string}], index: number) => {
      // Push each promise into the promises array
      promises.push(
        getAvatar(name).then(avatar => {
          feature.avatar = avatar;
        })
      );
    });
    // Update the newRankResult after all avatars are fetched for oneRank
    Promise.all(promises).then(() => {
      newRankResult.set(key, oneRank);
    });
  });

  // Wait for all promises to resolve before continuing
  await Promise.all(promises);

  rankResult = newRankResult;
}

// await getAllAvatar();
---

<Layout title={`${SITE.title}`}>
  <Header activeNav="rank" />
  <style>
    #content-container {
      display: flex;
      justify-content: center;
    }
    #main-content {
      display: flex;
      /* justify-content: center; */
      padding-left: 1rem;
      max-width: 48rem;
      padding-right: 1rem;
      width: 100%;
      flex-wrap: wrap;
    }

    #main-content > section {
      flex-grow: 1;
      max-width: 100%;
    }

    .icon-container {
      position: relative;
      display: inline-block;
    }

    .description {
      display: none;
      position: absolute;
      top: 5px;
      left: 35px;
      background-color: #333;
      color: #fff;
      padding: 5px;
      border-radius: 3px;
      white-space: nowrap;
      font-size: small;
    }

    .icon-container:hover .description,
    .icon-container.active .description {
      display: block;
    }
  </style>
  <script>
    // Get the avatar by Github API 'https://api.github.com/search/users?q='
    async function getAvatar(name: string) {
      let avatar = "https://github.com/identicons/" + name + ".png"; // random default avatar https://github.com/identicons/${name}.png
      const response = await fetch(`https://api.github.com/search/users?q=${name}`);
      const data = await response.json();
      if (data.hasOwnProperty("items") && data.items.length > 0) {
        avatar = data.items[0].avatar_url;
      }
      return avatar;
    }

    async function getAllAvatar() {
      // 获取所有带有 class="avatar-img" 的 img 元素
      const avatarImgs = document.querySelectorAll(".avatar-img");
      avatarImgs.forEach(async function(avatarImg) {
        // 检查avatarImg是否是HTMLImageElement
        if (!(avatarImg instanceof HTMLImageElement)) return;
        // 从每个 img 元素的 data-value 属性获取 GitHub 用户名
        const name = avatarImg.getAttribute("data-name");
        if (!name) return;
        const avatarUrl = await getAvatar(name);
        avatarImg.src = avatarUrl;
      });
    }

    // document.addEventListener("DOMContentLoaded", getAllAvatar);
  </script>
  <div id="content-container">
  <main id="main-content" class="mt-8 grid grid-cols-2 gap-8">
    {RANK_LIST.map(({ status, tabText, description }) => (
      <section id={status} class="mb-8 max-w-md prose-img:border-0">
        <div class="border rounded-md shadow-md p-4">
          <h2 class="text-xl font-bold mb-4">{tabText}{
            description ? (
              // icon for description (?)
              // <span class="text-sm text-gray-500"> - {description}</span>
              // Add icon, show the description when the icon is hovered
              <div class="icon-container">
                &nbsp;<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 inline-block info-icon" viewBox="0 0 20 20" fill="currentColor">
                  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm0-2a6 6 0 100-12 6 6 0 000 12zm0-10a1 1 0 100 2 1 1 0 000-2zm0 3a1 1 0 011 1v5a1 1 0 11-2 0V9a1 1 0 011-1z" clip-rule="evenodd" />
                </svg>
                <div class="description">{description}</div>
              </div>
            ) : null
          }</h2>
          <ol>
            {status != "all" ? (
              rankResult.get(status).map(([name, feature]: [string, { avatar: string, count: number }], index: number) => (
                <li class="flex justify-between items-center py-2">
                  <a href={`https://github.com/${name}`} target="_blank" rel="noopener noreferrer" class="flex items-center" title={name} >
                    <img src={feature.avatar} class="w-8 h-8 rounded-full me-3 avatar-img" alt={name} onerror="this.src='https://github.com/identicons/github.png'" data-name={name}/>
                    <span >{name}</span>
                  </a>
                  <span>{feature.count}</span>
                </li>
              ))
            ) : (
              <table class="table-auto w-full">
                {/* 动态生成表头，过滤掉 status 为 "all" 的项 */}
                <thead>
                  <tr>
                    <th class="px-4 py-2 text-left">ID</th>  {/* ID 左对齐 */}
                    {
                      RANK_LIST.filter(({ status }) => status !== "all").map(({ text }, index) => (
                        <th class="px-4 py-2">{text}</th>
                      ))
                    }
                  </tr>
                </thead>
                <tbody>
                  {
                    rankResult.get(status).map(([name, feature]: [string, { avatar: string, count: number }], index: number) => (
                      <tr class="text-center">
                        <td class="px-4 py-2 text-left">  {/* ID 左对齐 */}
                          <a href={`https://github.com/${name}`} target="_blank" rel="noopener noreferrer" class="flex items-center" title={name}>
                            <img src={feature.avatar} class="w-8 h-8 rounded-full mr-3 avatar-img" alt={name} onerror="this.src='https://github.com/identicons/github.png'" data-name={name} />
                            <span>{name}</span>
                          </a>
                        </td>
                        {
                          RANK_LIST
                            .filter(({ status }) => status !== "all")
                            .map(({ status }, index) => (
                              <td class="px-4 py-2">{rankResult.get(status)?.find(([name_part]: [string]) => name_part === name)?.[1]?.count || 0}</td>
                            ))
                        }
                      </tr>
                    ))
                  }
                </tbody>
              </table>
            )
          }
          </ol>
        </div>
      </section>
    ))}
  </main>
</div> 
  <Footer />
</Layout>

